Loading plugins in runtime

One of the WOLF objectives is to free the end-user of implementing anything, include and/or link plugins and packages in its applications.

This is accomplished with a combination of factory-based creation and automatic runtime loading of plugins.

The procedure has two main steps:

  • Search required plugins recursively in the YAML configuration file

  • Load required plugins

As result of this loading, the creators will be registered to the corresponding factories and the installed schema folders will be registered to the folder registry.

Important

The required plugins must be already compiled and installed.

WOLF loader

The responsible of loading the plugins (and ROS2 packages) in runtime is the class wolf::Loader:

#include <dlfcn.h>
#include <string>
#include <map>
#include <memory>
#include "yaml-cpp/yaml.h"

namespace wolf
{
class Loader
{
  protected:
    int                          flags_;
    std::map<std::string, void*> name_resources_;

  public:
    Loader(int flags = RTLD_LAZY);
    ~Loader();

    void load(std::string _libname_with_so);
    void loadPlugin(std::string _plugin);

    void close(std::string _libname_with_so);
    void closePlugin(std::string _plugin);

    void* isLoaded(std::string _libname_with_so) const;
    void* isLoadedPlugin(std::string _plugin) const;

    void                         searchAndLoadPlugins(const YAML::Node& _node);
    static std::set<std::string> searchPlugins(const YAML::Node& _node, std::list<YAML::Node>& _visited_nodes);
    static std::set<std::string> searchFieldsRecursive(const YAML::Node&      _node,
                                                       std::list<YAML::Node>& _visited_nodes,
                                                       const std::string&     field);
    size_t                       size() const;
};
typedef std::shared_ptr<Loader> LoaderPtr;

}  // namespace wolf

In Problem, there is a LoaderPtr that loads and keeps the loaded .so files.

Schema folder registry

Installed schemas

Along with the headers and the .so file, when installing a WOLF plugin the folder containing the schema files is also installed.

Part of the CMakeLists.txt file containing the schema folder installation.
#install schemas
install(DIRECTORY schema 
  DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME})

Folder registry

Analogously to the factories, WOLF has the class FolderRegistry that keeps a map of string, string being the key the plugin name and the value, the path of the installed schema folder. The registration of these folders is performed at plugin loading time. Then, after all necessary plugins are loaded in runtime, we can take the vector of paths containing installed schemas direcly from the FolderRegistry.

The following is the part of Problem::autoSetup method that loads the plugins and retrieves the installed schema folders.

_loader->searchAndLoadPlugins(server.getNode());

// Add the installed schema folders after optional input folders
server.addFolderSchema(FolderRegistry::getRegisteredFolders());

Note

When a plugin is loaded , youshould see the following message in the console that confirms that the schema folder of this plugin has been correctly registered:

FolderRegistry           <-- registered  'core' folder: /usr/local/include/wolf/core/schema

Note

The loading of ROS2 packages work analogously to plugins. It also registers subscribers and publishers creators and schema folders.